package cn.ipanel.bigdata.boot

import cn.ipanel.bigdata.boot.logger.Logger
import cn.ipanel.bigdata.utils.Util
import org.apache.commons.lang3.exception.ExceptionUtils

import scala.collection.mutable

/**
 * Author: lzz
 * Date: 2021/11/16 16:15
 */
class Bundle(url: String) extends Serializable {

  import Bundle._
  import Util._

  private[this] def init(): Unit = {
    if (url == null || "".equals(url) || !url.startsWith(Bundle.JOB))
      throw new IllegalArgumentException(s"request url protocol invalid[$url]")
    url.substring(url.indexOf(REGEX) + REGEX.length).split(PARAM_REGEX).foreach(set)
  }
  private[this] lazy val params: mutable.HashMap[String, String] = new mutable.HashMap()
  private[this] lazy val jobPath: String = {
    if (url.indexOf(REGEX) > 0) url.substring(JOB.length, url.indexOf(REGEX)) else url.substring(JOB.length)
  }
  private[this] def set(_kv: String): Unit = if (nonEmpty(_kv)) set(_kv.split(PARAM_KV_REGEX))
  private[this] def set(_kv: Array[String]): Unit = if (nonEmpty(_kv) && _kv.length == 2) set(_kv(0), _kv(1))
  private[this] def set(_k: String, _v: String): Unit = if (nonEmpty(_k) && nonEmpty(_v)) params.put(_k, _v)
  def get(_k: String): String = if (nonEmpty(_k) && params.contains(_k)) params(_k) else null
  def getAll: String = if (params.nonEmpty) params.mkString(",") else null
  def getJobClasspath: String = CLAZZ_ROOT + jobPath.replaceAll(REGEX_SEP, REGEX_PART)
  def getJobName: String = {
    if (jobPath.lastIndexOf(REGEX_SEP) > 0)
      jobPath.substring(jobPath.lastIndexOf(REGEX_SEP) + 1)
    else jobPath
  }

  override def toString: String = s"$url"
  init()
}

object Bundle {

  import Util._

  private[Bundle] final val JOB: String            = "job://"
  private[Bundle] final val REGEX: String          = "?"
  private[Bundle] final val REGEX_SEP: String      = "/"
  private[Bundle] final val REGEX_PART: String     = "."
  private[Bundle] final val PARAM_REGEX: String    = "&"
  private[Bundle] final val PARAM_KV_REGEX: String = "="
  private[Bundle] final val CLAZZ_ROOT: String     = "cn.ipanel.bigdata.job."

  def build(url: String): Bundle = {
    var obj: Bundle = null
    if (nonEmpty(url)) {
      try {
        obj = new Bundle(url)
      } catch {
        case e: Exception =>
          Logger.E(
            s""" build object Bundle[$url] failed.
               | Because: ${ExceptionUtils.getStackTrace(e)}
               |""".stripMargin)
      }
    }
    obj
  }
}